package ddemo.factory;



import ddemo.dao.IConnectionPool;
import ddemo.pojo.ConnData;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;

public class ConnectionPoll implements IConnectionPool {
    //静态代码块，注册连接，只执行一次
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //空闲线程的集合
    private List<Connection> freeConnection = new Vector<>();
    //活跃线权的集合
    private List<Connection> activeConnection = new Vector<>();
    //连接数
    private int count;
    //链接池配置数据
    private ConnData conndata;

    public ConnectionPoll(ConnData conndata) {
        this.conndata = conndata;
        initPool();
    }

    private void initPool() {
        //System.out.println("init已调用");
        //判断配置文件是否为空
        if (conndata == null) {
            //为空抛出异常
            throw new RuntimeException("配置文件为空");
        }
        //初始化池，创建连接，放入连接池中
        for (int i = 0; i < conndata.getInitConnections(); i++) {
            //调用creatConnection()创建连接
            Connection connection = createConnection();
            if (connection != null) {
                count++;
                freeConnection.add(connection);
            }
        }

//        调试用调出空池中的连接数
//        System.out.println(freeConnection.size());
    }


    private Connection createConnection() {
        Connection connection=null;
        try {
            //获取连接
             connection = DriverManager.getConnection(conndata.getUrl(),conndata.getUserName(),conndata.getPassword());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        //返回连接
        return connection;




    }

    @Override
    public synchronized Connection getConnection() {
        Connection connection=null;
//        System.out.println(freeConnection.size());
        //判断是否有空闲线程
        if(freeConnection.size()>0){
            //有则获取空池中一个
            connection=freeConnection.get(0);
            //将获取链接从空池中取出
            freeConnection.remove(0);
            //加入使用池子
            activeConnection.add(connection);
        }else{
            //如果没有空闲线程，则判断现有线程数是否大于最大线程数
            if(count<conndata.getMaxActiveConnections()){
                //不大于则创建一个新链接，并使用
                connection=createConnection();
                if(connection!=null){
                    count++;
                    //加入使用池
                    activeConnection.add(connection);
                }
            }
            else{
                while(count<conndata.getMaxActiveConnections()) {
                    try {
                        //若线程数已最大，等待线程自动销毁
                        wait(conndata.getConnectionTimeOut());
                        //销毁后
                        connection = createConnection();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return null;
                    }
                }
            }
        }
        return connection;
    }

    @Override
    public synchronized void releaseConnection(Connection connection) {
    if(freeConnection.size()<conndata.getMaxConnections()){
        freeConnection.add(connection);
    }
    else{
        try {activeConnection.remove(connection);
            connection.close();
            count--;
            notifyAll();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }


    }

    }
}
